// FileStreams.h

#ifndef __FILESTREAMS_H
#define __FILESTREAMS_H

#ifdef _WIN32
#define USE_WIN_FILE
#endif

#ifdef USE_WIN_FILE
#include "FileIO.h"
#else
#include "../../Common/C_FileIO.h"
#endif


#include "IStream.h"

class ATL_NO_VTABLE CInFileStream:
	public CComObjectRootEx<CComSingleThreadModel>,
  public IInStream,
  public IStreamGetSize 
{
public:
	BEGIN_COM_MAP(CInFileStream)
		COM_INTERFACE_ENTRY(IInStream)
		COM_INTERFACE_ENTRY(IStreamGetSize)		
	END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

  #ifdef USE_WIN_FILE
  Common::IO::CInFile File;
  #ifdef SUPPORT_DEVICE_FILE
  UINT64 VirtPos;
  UINT64 PhyPos;
  UINT64 BufferStartPos;
  BYTE *Buffer;
  UINT32 BufferSize;
  #endif
  #else
  NC::NFile::NIO::CInFile File;
  #endif
  virtual ~CInFileStream();

  #ifdef SUPPORT_DEVICE_FILE
  CInFileStream();
  #endif
  
  bool Open(LPCTSTR fileName);


  bool OpenShared(LPCTSTR fileName, bool shareForWrite);

  

  STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
  STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition);

  STDMETHOD(GetSize)(UINT64 *size);
};

class ATL_NO_VTABLE CStdInFileStream:
	public CComObjectRootEx<CComSingleThreadModel>,
  public ISequentialInStream 
{
public:
  
  BEGIN_COM_MAP(CStdInFileStream)
		COM_INTERFACE_ENTRY(ISequentialInStream)
	END_COM_MAP()



	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

  
  STDMETHOD(Read)(void *data, UINT32 size, UINT32 *processedSize);
};

class ATL_NO_VTABLE COutFileStream:
	public CComObjectRootEx<CComSingleThreadModel>,
  public IOutStream 
{
  #ifdef USE_WIN_FILE
  Common::IO::COutFile File;
  #else
  NC::NFile::NIO::COutFile File;
  #endif
public:
	BEGIN_COM_MAP(COutFileStream)
		COM_INTERFACE_ENTRY(IOutStream)
	END_COM_MAP()


	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}
  
  bool Create(LPCTSTR fileName, bool createAlways)
  {
    ProcessedSize = 0;
    return File.Create(fileName, createAlways);
  }
  bool Open(LPCTSTR fileName, DWORD creationDisposition)
  {
    ProcessedSize = 0;
    return File.Open(fileName, creationDisposition);
  }
  
  
  HRESULT Close();
  
  UINT64 ProcessedSize;

  #ifdef USE_WIN_FILE
  bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
  {
    return File.SetTime(cTime, aTime, mTime);
  }
  bool SetMTime(const FILETIME *mTime) {  return File.SetMTime(mTime); }
  #endif


  STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
  STDMETHOD(Seek)(INT64 offset, UINT32 seekOrigin, UINT64 *newPosition);
  STDMETHOD(SetSize)(UINT64 newSize);
};

class ATL_NO_VTABLE CStdOutFileStream:
	public CComObjectRootEx<CComSingleThreadModel>,
  public ISequentialOutStream 
{
public:
  
	BEGIN_COM_MAP(CStdOutFileStream)
		COM_INTERFACE_ENTRY(ISequentialOutStream)
	END_COM_MAP()


	DECLARE_PROTECT_FINAL_CONSTRUCT()

	HRESULT FinalConstruct()
	{
		return S_OK;
	}

	void FinalRelease()
	{
	}

 
  STDMETHOD(Write)(const void *data, UINT32 size, UINT32 *processedSize);
};

#endif
